package com.liuxm.es.test;

import cn.hutool.json.JSONUtil;
import com.liuxm.es.User;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

/**
 * @author liuxm
 * @version 1.0
 * @date 2021/3/19 20:08
 */
public class DocumentSearch {

    RestHighLevelClient client;

    @Before
    public void before() {
        client = new RestHighLevelClient(RestClient.builder(
                new HttpHost("192.168.31.11", 9200, "http")
        ));
    }

    @After
    public void after() throws IOException {
        client.close();
    }

    /**
     * 查询全部
     */
    @Test
    public void matchAll() throws IOException {
        SearchRequest request = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);

    }

    /**
     * 分词查询
     */
    @Test
    public void match() throws IOException {
        SearchRequest request = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("note", "同学"));
        request.source(sourceBuilder);

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);


    }

    /**
     * 词条查询
     */
    @Test
    public void terms() throws IOException {
        SearchRequest request = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //==================================================================
        sourceBuilder.query(QueryBuilders.termQuery("note", "学唱歌"));
        //==================================================================
        request.source(sourceBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);
    }


    /**
     * 范围查询
     */
    @Test
    public void range() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.rangeQuery("age").gt(20).lt(30));

        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);


    }

    /**
     * 模糊查询
     */
    @Test
    public void fuzzy() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.fuzzyQuery("note", "学唱歌"));
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);

    }


    /**
     * 布尔查询
     * note     同学
     * age      18 - 28
     * gender   1
     */
    @Test
    public void bool() throws IOException {
        SearchRequest searchRequest = new SearchRequest("user");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("note", "同学"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(18).lte(28));
        boolQueryBuilder.filter(QueryBuilders.termQuery("gender", "1"));
        sourceBuilder.query(boolQueryBuilder);

        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);

        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);

        }
        System.out.println("总数：" + total);
    }

    @Test
    public void bool2() throws IOException {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.matchQuery("note","同学"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("age").gte(18).lte(28));
        boolQueryBuilder.filter(QueryBuilders.termQuery("gender","1"));

        sourceBuilder.query(boolQueryBuilder);

        showResult("user",sourceBuilder);
    }


    private void showResult(String indices, SearchSourceBuilder sourceBuilder) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indices);
        searchRequest.source(sourceBuilder);
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = searchResponse.getHits();
        long total = searchHits.getTotalHits().value;
        for (SearchHit doc : searchHits.getHits()) {
            User user = JSONUtil.toBean(doc.getSourceAsString(), User.class);
            System.out.println(user);
        }
        System.out.println("总数：" + total);
    }


}
